Trò chơi đua xe động vật trong UNITY Engine
- VerticalScrollSnap.cs
- Layout /
- AnimalRacing /
- Scripts /
- Assets /
- project /
2 /// Sourced from - http://forum.unity3d.com/threads/scripts-useful-4-6-scripts-collection.264161/page-2#post-1945602
3 /// Updated by SimonDarksideJ - removed dependency on a custom ScrollRect script. Now implements drag interfaces and standard Scroll Rect.
4 /// Updated by SimonDarksideJ - major refactoring on updating current position and scroll management
5
6 using UnityEngine.EventSystems;
7
8 namespace UnityEngine.UI.Extensions
9 {
10 [RequireComponent(typeof(ScrollRect))]
11 [AddComponentMenu("Layout/Extensions/Vertical Scroll Snap")]
12 public class VerticalScrollSnap : ScrollSnapBase, IEndDragHandler
13 {
14 void Start()
15 {
16 _isVertical = true;
17 _childAnchorPoint = new Vector2(0.5f,0);
18 _currentPage = StartingScreen;
19 UpdateLayout();
20 }
21
22 void Update()
23 {
24 if (!_lerp && _scroll_rect.velocity == Vector2.zero)
25 {
26 if (!_settled && !_pointerDown)
27 {
28 if (!IsRectSettledOnaPage(_screensContainer.localPosition))
29 {
30 ScrollToClosestElement();
31 }
32 }
33 return;
34 }
35 else if (_lerp)
36 {
37 _screensContainer.localPosition = Vector3.Lerp(_screensContainer.localPosition, _lerp_target, transitionSpeed * Time.deltaTime);
38 if (Vector3.Distance(_screensContainer.localPosition, _lerp_target) < 0.1f)
39 {
40 _lerp = false;
41 EndScreenChange();
42 }
43 }
44
45 CurrentPage = GetPageforPosition(_screensContainer.localPosition);
46
47 //If the container is moving check if it needs to settle on a page
48 if (!_pointerDown)
49 {
50 if (_scroll_rect.velocity.y > 0.01 || _scroll_rect.velocity.y < -0.01)
51 {
52 // if the pointer is released and is moving slower than the threshold, then just land on a page
53 if (IsRectMovingSlowerThanThreshold(0))
54 {
55 ScrollToClosestElement();
56 }
57 }
58 }
59 }
60
61 private bool IsRectMovingSlowerThanThreshold(float startingSpeed)
62 {
63 return (_scroll_rect.velocity.y > startingSpeed && _scroll_rect.velocity.y < SwipeVelocityThreshold) ||
64 (_scroll_rect.velocity.y < startingSpeed && _scroll_rect.velocity.y > -SwipeVelocityThreshold);
65 }
66
67 public void DistributePages()
68 {
69 _screens = _screensContainer.childCount;
70 _scroll_rect.verticalNormalizedPosition = 0;
71
72 float _offset = 0;
73 float _dimension = 0;
74 Rect panelDimensions = gameObject.GetComponent<RectTransform>().rect;
75 float currentYPosition = 0;
76 var pageStepValue = _childSize = (int)panelDimensions.height * ((PageStep == 0) ? 3 : PageStep);
77
78 for (int i = 0; i < _screensContainer.transform.childCount; i++)
79 {
80 RectTransform child = _screensContainer.transform.GetChild(i).gameObject.GetComponent<RectTransform>();
81 currentYPosition = _offset + i * pageStepValue;
82 child.sizeDelta = new Vector2(panelDimensions.width, panelDimensions.height);
83 child.anchoredPosition = new Vector2(0f, currentYPosition);
84 child.anchorMin = child.anchorMax = child.pivot = _childAnchorPoint;
85 }
86
87 _dimension = currentYPosition + _offset * -1;
88
89 _screensContainer.GetComponent<RectTransform>().offsetMax = new Vector2(0f, _dimension);
90 }
91
92 /// <summary>
93 /// Add a new child to this Scroll Snap and recalculate it's children
94 /// </summary>
95 /// <param name="GO">GameObject to add to the ScrollSnap</param>
96 public void AddChild(GameObject GO)
97 {
98 AddChild(GO, false);
99 }
100
101 /// <summary>
102 /// Add a new child to this Scroll Snap and recalculate it's children
103 /// </summary>
104 /// <param name="GO">GameObject to add to the ScrollSnap</param>
105 /// <param name="WorldPositionStays">Should the world position be updated to it's parent transform?</param>
106 public void AddChild(GameObject GO, bool WorldPositionStays)
107 {
108 _scroll_rect.verticalNormalizedPosition = 0;
109 GO.transform.SetParent(_screensContainer, WorldPositionStays);
110 InitialiseChildObjectsFromScene();
111 DistributePages();
112 if (MaskArea) UpdateVisible();
113
114 SetScrollContainerPosition();
115 }
116
117 /// <summary>
118 /// Remove a new child to this Scroll Snap and recalculate it's children
119 /// *Note, this is an index address (0-x)
120 /// </summary>
121 /// <param name="index"></param>
122 /// <param name="ChildRemoved"></param>
123 public void RemoveChild(int index, out GameObject ChildRemoved)
124 {
125 ChildRemoved = null;
126 if (index < 0 || index > _screensContainer.childCount)
127 {
128 return;
129 }
130 _scroll_rect.verticalNormalizedPosition = 0;
131
132 Transform child = _screensContainer.transform.GetChild(index);
133 child.SetParent(null);
134 ChildRemoved = child.gameObject;
135 InitialiseChildObjectsFromScene();
136 DistributePages();
137 if (MaskArea) UpdateVisible();
138
139 if (_currentPage > _screens - 1)
140 {
141 CurrentPage = _screens - 1;
142 }
143
144 SetScrollContainerPosition();
145 }
146
147 /// <summary>
148 /// Remove all children from this ScrollSnap
149 /// </summary>
150 /// <param name="ChildrenRemoved"></param>
151 public void RemoveAllChildren(out GameObject[] ChildrenRemoved)
152 {
153 var _screenCount = _screensContainer.childCount;
154 ChildrenRemoved = new GameObject[_screenCount];
155
156 for (int i = _screenCount - 1; i >= 0; i--)
157 {
158 ChildrenRemoved[i] = _screensContainer.GetChild(i).gameObject;
159 ChildrenRemoved[i].transform.SetParent(null);
160 }
161
162 _scroll_rect.verticalNormalizedPosition = 0;
163 CurrentPage = 0;
164 InitialiseChildObjectsFromScene();
165 DistributePages();
166 if (MaskArea) UpdateVisible();
167 }
168
169 private void SetScrollContainerPosition()
170 {
171 _scrollStartPosition = _screensContainer.localPosition.y;
172 _scroll_rect.verticalNormalizedPosition = (float)(_currentPage) / (_screens - 1);
173 }
174
175 /// <summary>
176 /// used for changing / updating between screen resolutions
177 /// </summary>
178 public void UpdateLayout()
179 {
180 _lerp = false;
181 DistributePages();
182 if (MaskArea) UpdateVisible();
183 SetScrollContainerPosition();
184 OnCurrentScreenChange(_currentPage);
185 }
186
187 private void OnRectTransformDimensionsChange()
188 {
189 if (_childAnchorPoint != Vector2.zero)
190 {
191 UpdateLayout();
192 }
193 }
194
195 #region Interfaces
196 /// <summary>
197 /// Release screen to swipe
198 /// </summary>
199 /// <param name="eventData"></param>
200 public void OnEndDrag(PointerEventData eventData)
201 {
202 _pointerDown = false;
203
204 if (_scroll_rect.vertical)
205 {
206 if (UseFastSwipe)
207 {
208 //If using fastswipe - then a swipe does page next / previous
209 if ((_scroll_rect.velocity.y > 0 && _scroll_rect.velocity.y > FastSwipeThreshold) ||
210 _scroll_rect.velocity.y < 0 && _scroll_rect.velocity.y < -FastSwipeThreshold)
211 {
212 _scroll_rect.velocity = Vector3.zero;
213 if (_startPosition.y - _screensContainer.localPosition.y > 0)
214 {
215 NextScreen();
216 }
217 else
218 {
219 PreviousScreen();
220 }
221 }
222 else
223 {
224 ScrollToClosestElement();
225 }
226 }
227 }
228 }
229 #endregion
230 }
231 }
Credit BinaryX, SimonDarksideJ
Sourced from - http:forum.unity3d.comthreadsscripts-useful-4-6-scripts-collection.264161page-2#post-1945602
Updated by SimonDarksideJ - removed dependency on a custom ScrollRect script. Now implements drag interfaces and standard Scroll Rect.
Updated by SimonDarksideJ - major refactoring on updating current position and scroll management
If the container is moving check if it needs to settle on a page
if the pointer is released and is moving slower than the threshold, then just land on a page
Add a new child to this Scroll Snap and recalculate it's children
GameObject to add to the ScrollSnap
Add a new child to this Scroll Snap and recalculate it's children
GameObject to add to the ScrollSnap
Should the world position be updated to it's parent transform?
Remove a new child to this Scroll Snap and recalculate it's children
*Note, this is an index address (0-x)
Remove all children from this ScrollSnap
used for changing updating between screen resolutions
Release screen to swipe
If using fastswipe - then a swipe does page next previous